home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Workbench Add-On
/
Workbench Add-On - Volume 1.iso
/
BBS-Archive
/
Comm
/
AmiTCP30b2.lha
/
src
/
appl
/
napsaterm
/
keymap.c
< prev
next >
Wrap
C/C++ Source or Header
|
1994-05-14
|
7KB
|
257 lines
RCS_ID_C "$Id: keymap.c,v 3.3 1994/05/14 12:43:33 ppessi Exp $";
/*
* Keyboard handling routines
*
* $Log: keymap.c,v $
* Revision 3.3 1994/05/14 12:43:33 ppessi
* Cleaned up the keyboard conversion code,
* it fully supports CTRL8BIT option now.
*
* Revision 3.2 1994/05/12 10:44:49 ppessi
* Added application keypad handling (original code by R. Knop)
*
*/
#include <string.h>
#include <stdio.h>
#include "nifty.h"
#include "amiga.h"
#include "display.h"
#include "wimp.h"
#include "nio.h"
#include "napsaprefs.h"
#include <devices/keymap.h>
#include <intuition/intuition.h>
struct IOStdReq consolereq = { 0 };
#define ConsoleDevice (consolereq.io_Device)
#ifdef USE_PRAGMAS
#include <proto/keymap.h>
#include <clib/console_protos.h>
#include <pragmas/console_pragmas.h>
#endif
#ifdef USE_INLINE
#include <inline/proto.h>
#include <inline/console.h>
#endif
#ifdef USE_CLIB
#include <clib/keymap_protos.h>
#include <clib/console_protos.h>
#endif
struct KeyMap *default_map = NULL; /* used in `international' mode */
struct KeyMap *used_map = NULL; /* used in multinational/national mode */
char keyMapDir[] = "Devs:keymaps/";
#define MAXKEYMAPLEN 32
static struct KeyMap *findmap(const char *name)
{
struct KeyMapNode *keymap_n;
BPTR keySegs;
char fullKeyMapName[sizeof(keyMapDir) + MAXKEYMAPLEN];
struct KeyMapResource *keyMapBase =
(struct KeyMapResource *)OpenResource("keymap.resource");
if (!keyMapBase)
return NULL;
/* Is it already loaded? */
keymap_n = (struct KeyMapNode *)
FindName(&(keyMapBase->kr_List), (UBYTE *)name);
if (!keymap_n) {
/* Not found, we load it from devs:keymaps */
strcpy(fullKeyMapName, keyMapDir);
strncat(fullKeyMapName, name, MAXKEYMAPLEN);
keySegs = LoadSeg(fullKeyMapName);
if (!keySegs)
return NULL;
keymap_n = (struct KeyMapNode *)((LONG *) (keySegs << 2) + 1);
AddHead(&(keyMapBase->kr_List), (struct Node *)keymap_n);
}
return &(keymap_n->kn_KeyMap);
}
/*
* Use named keymap. If map is non-NULL, use it.
* Default map is treated as -1
* Return pointer to new keymap
*
* If named keymap can not be found from memory, load it from disk
*/
void *setmap(const char *name, void *map)
{
if (map) {
if (map != (void *)-1) {
used_map = map;
} else {
used_map = NULL;
}
} else if (name) {
used_map = findmap(name);
} else {
used_map = default_map;
}
if (used_map)
return used_map;
else
return (void *)-1;
}
/*
* Initialize keymaps
*/
void initkeys(void)
{
if(OpenDevice("console.device", -1L, (struct IORequest *)&consolereq, 0L))
fatalError("Failure to open console.device");
default_map = setmap(np.keymap, NULL);
if (default_map == (struct KeyMap *)-1)
default_map = NULL;
}
/*
* Free resources allocated by this module
*/
void deinitkeys(void)
{
if (ConsoleDevice)
CloseDevice((struct IORequest *)&consolereq);
ConsoleDevice = NULL;
}
/*
* Handle an Intuition RAWKEY message.
*
* The function keys, cursor keys, and keypad may have either the
* native Amiga values, or the vt100/vt52 values.
*/
#define ISCURSOR(c) (((c)>75) && ((c)<80))
#ifdef OWNICONIFY
#define ICONIFY(c, q) (((q) & AMIGALEFT) && ((q) & AMIGARIGHT) && ((c) == 23))
#endif
static long keyconvert(struct IntuiMessage *msg, char *kbuffer, long kbsize);
void dokeys(struct IntuiMessage *msg)
{
UBYTE buf[512], *convertp = buf + sizeof buf / 2, *endp, *sendp;
int count;
static const char applkeypad[0x60] =
{
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 'p', /* 0 */
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 'q', 'r', 's', /* 1 2 3 */
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 't', 'u', 'v', /* 4 5 6 */
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 'n', 'w', 'x', 'y', /* . 7 8 9 */
0, 0, 0, 'M', 0, 0, 0, 0, /* Enter */
0, 0, 'm', 0, 0, 0, 0, 0, /* - */
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 'P', 'Q', 'R', 'S', 'l', 0, /* ( ) / * + */
};
if (np.applkeypad && msg->Code < 0x60 &&
applkeypad[(BYTE)(msg->Code)] != 0) {
/* Application keypad handling */
convertp[0] = CTRL8('O');
convertp[1] = applkeypad[(BYTE)(msg->Code)];
count = 2;
} else if (ISCURSOR(msg->Code)) {
/* Cursor keys */
count = 2;
convertp[1] = msg->Code - 76 + 'A';
switch (np.cursormap) {
case CURSOR_VT100:
convertp[0] = CTRL8('['); /* CSI */
break;
case CURSOR_ANSI:
convertp[0] = CTRL8('O');
break;
case CURSOR_VT52:
convertp[0] = 033;
break;
default:
count = 0;
}
} else {
count = keyconvert(msg, convertp, sizeof(buf) / 2);
}
/* If alt is treated as meta, we add ESC before a single char */
if (np.altismeta && (msg->Qualifier & IEQUALIFIER_LALT) && count == 1) {
buf[0] = ESC;
sendp = buf + 1;
} else {
sendp = buf;
}
ReplyMsg((struct Message *)msg);
/* Convert keycodes before sending them */
if (count != 0) {
for (endp = convertp + count; convertp < endp; ) {
UBYTE c = *convertp++;
if ((c & 0xe0) == 0x80 && !np.ctrl8bit) {
/* 8-bit control codes are converted into ESC-sequences */
*sendp++ = ESC;
c += '@' - 0x80;
} else if (c == '\015' && np.ansi_LNM) {
/* CR is converted into CRLF pair */
*sendp++ = c;
c = '\012';
} else if (np.national == NAT_7BIT) {
/* Characters are converted into national codes */
c = national_send[c];
}
*sendp++ = c;
}
nwrite(buf, sendp - buf);
}
}
static long keyconvert(struct IntuiMessage *msg, char *kbuffer, long kbsize)
{
struct InputEvent ievent;
if(msg->Code & IECODE_UP_PREFIX)
return 0;
ievent.ie_Code = msg->Code;
/* swap BS and DEL */
if (ievent.ie_Code == 70 && np.delete)
ievent.ie_Code = 65;
else if (ievent.ie_Code == 65 && np.backspace)
ievent.ie_Code = 70;
ievent.ie_NextEvent = 0;
ievent.ie_SubClass = 0;
ievent.ie_Class = IECLASS_RAWKEY;
ievent.ie_Qualifier = msg->Qualifier;
ievent.ie_position.ie_addr = *((APTR *)msg->IAddress);
/* This waz a mysterious bug */
if (np.altismeta) { /* left alt is meta char */
ievent.ie_Qualifier &= ~IEQUALIFIER_LALT;
ievent.ie_position.ie_dead.ie_prev1DownQual &= ~IEQUALIFIER_LALT;
ievent.ie_position.ie_dead.ie_prev2DownQual &= ~IEQUALIFIER_LALT;
}
return (RawKeyConvert(&ievent, kbuffer, kbsize,
np.national ? used_map : default_map));
}